#include "sbrush_instrument.h"
#include "dag_threading.h"

using namespace sbrush;
using namespace std;
using namespace dag;

Instrument::Instrument() 
:	m_Mutex(new Mutex())
{
}

Instrument::~Instrument() throw() {
}

CannotHandleInstrumentState::CannotHandleInstrumentState(const string& reason)
:	AcsError("cannot handle instrument state"),
	m_Reason(reason)
{
}

CannotHandleInstrumentState::~CannotHandleInstrumentState() throw() {
}

const char* CannotHandleInstrumentState::why() const {
	return m_Reason.c_str();
}

void Instrument::addListener(InstrumentListener* listener) {
	ScopedLock sl(*m_Mutex);
	m_Listeners.insert(listener);
}

void Instrument::removeListener(InstrumentListener* listener) {
	ScopedLock sl(*m_Mutex);
	m_Listeners.erase(listener);
}
	
void Instrument::setState(const InstrumentState& state) {
	/* this is the default functionality of the instrument. This can be
	 * overidden by a subclass if they wish to do something here. Or they can
	 * throw an exception if they don't want this method implemented and would
	 * rather generate the state from within the class. 
	 */
	broadcastState(state);
}

void Instrument::broadcastState(const InstrumentState& state) {
	ScopedLock sl(*m_Mutex);
	set<InstrumentListener*>::iterator lIter;
	for (lIter = m_Listeners.begin(); lIter != m_Listeners.end(); lIter++) {
		(*lIter)->instrumentCallback(this, state);
	}
}

